package com.asm.service;

import com.asm.dto.PageResult;
import com.asm.entity.sys.Maintenance;
import com.asm.repository.MaintenanceRepository;
import com.asm.util.SnowflakeIdWorker;
import com.asm.vo.sys.MaintenanceVo;
import com.asm.vo.sys.SpotVo;
import com.asm.vo.sys.WorkOrderVo;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author zhangyufu
 * @description service层的维修申请服务
 * @date 2019/7/12
 */
@Service
public class MaintenanceService {
    @Resource
    private MaintenanceRepository maintenanceRepository;

    @Resource
    private SpotService spotService;

    @Resource
    private UserService userService;

    @Resource
    private WorkOrderService workOrderService;

    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;

    /**
     * 获取维修申请列表
     *
     * @param page 页面对象
     * @return 维修申请列表
     */
    private List<MaintenanceVo> getMaintenanceVoList(Page<Maintenance> page) {
        List<MaintenanceVo> list = new ArrayList<>();
        for (Maintenance maintenance : page.getContent()) {
            MaintenanceVo maintenanceVo = new MaintenanceVo();
            BeanUtils.copyProperties(maintenance, maintenanceVo);
            list.add(maintenanceVo);
        }
        return list;
    }

    /**
     * 分页查询所有维修申请
     *
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 分页形式的维修申请列表
     */
    public PageResult<MaintenanceVo> findAllMaintenances(Integer pageNumber, Integer pageSize) {
        Page<Maintenance> page = maintenanceRepository.findAll(PageRequest.of(pageNumber, pageSize));
        return new PageResult<>(pageNumber, pageSize, page.getTotalPages(), getMaintenanceVoList(page));
    }

    /**
     * 分页查询所有维修申请，查询结果按状态排序
     *
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 分页并排序的维修申请
     */
    public PageResult<MaintenanceVo> getMaintenancesBySort(Integer pageNumber, Integer pageSize) {
        List<Maintenance> list1 = maintenanceRepository.findByStatusAndIsDel("待维修", false);
        List<Maintenance> list2 = maintenanceRepository.findByStatusAndIsDel("维修中", false);
        List<Maintenance> list3 = maintenanceRepository.findByStatusAndIsDel("维修完成", false);
        List<List<Maintenance>> maintenanceLists = new ArrayList<>();
        maintenanceLists.add(list1);
        maintenanceLists.add(list2);
        maintenanceLists.add(list3);
        List<MaintenanceVo> maintenanceList = new ArrayList<>();
        for (int i = 0; i < maintenanceLists.size(); i++) {
            List<Maintenance> list = maintenanceLists.get(i);
            for (int j = 0; j < list.size(); j++) {
                MaintenanceVo maintenanceVo = new MaintenanceVo();
                BeanUtils.copyProperties(list.get(j), maintenanceVo);
                maintenanceList.add(maintenanceVo);
            }
        }
        List<MaintenanceVo> subList = null;
        int totalPages = maintenanceList.size() / pageSize;
        if (maintenanceList.size() % pageSize != 0) {
            totalPages++;
        }
        if (pageNumber >= 0 && pageNumber < totalPages) {
            int start = pageNumber * pageSize;
            int end = start + pageSize;
            if (pageNumber == totalPages - 1 && end > maintenanceList.size()) {
                end = maintenanceList.size();
            }
            subList = maintenanceList.subList(start, end);
        }
        return new PageResult<>(pageNumber, pageSize, totalPages, subList);
    }

    /**
     * 根据id查询维修申请
     *
     * @param id 维修申请编号
     * @return 维修申请
     */
    public MaintenanceVo findMaintenanceById(Long id) {
        MaintenanceVo maintenanceVo = new MaintenanceVo();
        if (maintenanceRepository.findById(id).isPresent()) {
            Maintenance maintenance = maintenanceRepository.findById(id).get();
            BeanUtils.copyProperties(maintenance, maintenanceVo);
        }
        return maintenanceVo;
    }

    /**
     * 根据顾客编号查询报障单
     *
     * @param customerId 顾客编号
     * @param pageNumber 当前页码
     * @param pageSize   页面大小
     * @return 报障单
     */
    public PageResult<MaintenanceVo> findMaintenanceByCustomerId(Long customerId, Integer pageNumber, Integer pageSize) {
        Pageable page = PageRequest.of(pageNumber, pageSize);
        Page<Maintenance> maintenances = maintenanceRepository.findByCustomerId(customerId, page);
        return new PageResult<>(pageNumber, pageSize, maintenances.getTotalPages(), getMaintenanceVoList(maintenances));
    }

    /**
     * 根据业务员编号获取报障列表
     *
     * @param sellId 业务员编号
     * @return 报障列表
     */
    public List<MaintenanceVo> findMaintenanceBySellId(Long sellId) {
        List<Maintenance> maintenanceList = maintenanceRepository.findBySellIdAndIsDel(sellId, false);
        List<MaintenanceVo> maintenanceVoList = new ArrayList<>();
        for (Maintenance maintenance : maintenanceList) {
            MaintenanceVo maintenanceVo = new MaintenanceVo();
            BeanUtils.copyProperties(maintenance, maintenanceVo);
            maintenanceVoList.add(maintenanceVo);
        }
        return maintenanceVoList;
    }

    /**
     * 添加维修申请
     *
     * @param maintenanceVo 维修申请
     * @return 新生成的维修申请的id
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addMaintenance(MaintenanceVo maintenanceVo) {
        Maintenance maintenance = new Maintenance();
        BeanUtils.copyProperties(maintenanceVo, maintenance);
        maintenance.setId(snowflakeIdWorker.nextId());
        maintenance.setCreateAt(new Date());
        maintenance.setCreateBy(1L);
        maintenance.setUpdateAt(new Date());
        maintenance.setUpdateBy(1L);
        maintenanceRepository.save(maintenance);
        return maintenance.getId();
    }

    /**
     * 更新维修申请
     *
     * @param maintenanceVo 维修申请
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateMaintenance(MaintenanceVo maintenanceVo) {
        Maintenance maintenance = maintenanceRepository.findById(maintenanceVo.getId()).get();
        BeanUtils.copyProperties(maintenanceVo, maintenance);
        maintenance.setUpdateBy(1L);
        maintenance.setUpdateAt(new Date());
        maintenanceRepository.save(maintenance);
    }

    /**
     * 根据Id删除维修申请
     *
     * @param id 维修申请编号
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteMaintenance(Long id) {
        Maintenance maintenance = maintenanceRepository.findById(id).get();
        maintenance.setIsDel(true);
        maintenance.setUpdateBy(1L);
        maintenance.setUpdateAt(new Date());
        maintenanceRepository.save(maintenance);
    }

    /**
     * 发送报障维修信息并生成工单
     *
     * @param maintenanceVo 损坏的广告位信息
     */
    public void repairApply(MaintenanceVo maintenanceVo) {
        maintenanceVo.setStatus("待维修");
        this.addMaintenance(maintenanceVo);
        SpotVo spotVo = spotService.findSpotById(maintenanceVo.getSpotId());
        spotVo.setIsRepair(true);
        spotVo.setIsBusy(true);
        spotService.updateSpot(spotVo);
    }

    /**
     * 管理员安排工人
     *
     * @param maintenanceVo 维修申请信息
     */
    public void assignTask(MaintenanceVo maintenanceVo) {
        WorkOrderVo workOrderVo = new WorkOrderVo();
        List<Map<String, Object>> workers = userService.findUserByRoleCode("worker");
        Random random = new Random(workers.size());
        int index = random.nextInt(workers.size());
        Map<String, Object> worker = workers.get(index);
        workOrderVo.setWorkerId((Long) worker.get("userId"));
        workOrderVo.setOrderId(maintenanceVo.getId());
        workOrderVo.setStatus("未完成");
        workOrderVo.setWorkType("维修单");
        Long id = workOrderService.addWorkOrder(workOrderVo);
        maintenanceVo.setWorkerOrderId(id);
        maintenanceVo.setStatus("维修中");
        this.updateMaintenance(maintenanceVo);
    }

}
